from flask import current_app
from flask import request, jsonify
from flask import session

from info import constants
from info import db
from info.models import News, Category
from info.utils.qiniu_storage import storage
from info.utils.response_code import RET
from . import profile_blu
from flask import redirect, render_template, g
from info.utils.common import user_login_data

@profile_blu.route('/info')
@user_login_data
def user_info():
    user = g.user
    if not user:
        # 用户未登录，重定向到主页
        return redirect('/')

    data = {
        "user_info": user.to_dict() if user else None
    }

    return render_template("news/user.html", data = data)


"""
分为"GET", "POST"
展示基本资料页面，处理修改基本资料请求
1. 获取参数
2. 判空、校验
3. 保存更改的数据
   将 session 中保存的数据进行实时更新
4. 返回操作结果
"""

@profile_blu.route('/base_info', methods=["GET", "POST"])
@user_login_data
def base_info():
    # 展示基本资料页面，处理修改基本资料请求
    user = g.user
    if not user:
        # 用户未登录，重定向到主页
        return redirect('/')

    if request.method == "GET":
        data = {
            "user_info": user.to_dict() if user else None
        }

        return render_template("news/user_base_info.html", data = data)

    # 提交数据
    # 1. 获取参数
    data_dict = request.json
    signature = data_dict.get("signature")
    nick_name = data_dict.get("nick_name")
    gender = data_dict.get("gender")

    # 2. 判空、校验数据
    if not all([nick_name, gender, signature]):
        return jsonify(errno = RET.PARAMERR, errmsg = "参数有误1")

    if gender not in ['MAN', 'WOMAN']:
        return jsonify(errno = RET.PARAMERR, errmsg = "参数有误2")

    # 3. 保存更改的数据
    user.nick_name = nick_name
    user.gender = gender
    user.signature = signature
    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno = RET.DBERR, errmsg = "保存数据失败")

    # 将 session 中保存的数据进行实时更新
    session["nick_name"] = nick_name

    # 4. 返回操作结果
    return jsonify(errno = RET.OK, errmsg = "更新成功")


@profile_blu.route("/pic_info", methods=["GET", "POST"])
@user_login_data
def pic_info():
    """
    展示上传头像页面，处理上传头像请求
    1. 获取上传的文件
    2. 把文件上传到七牛云
    3. 把头像信息更新到当前用户的模型中 user.avatar_url = storage返回的url ，并提交数据库
    4. 返回上传的结果(带上图片url返回给前端)
    """

    # 展示上传页面，处理上传头像请求
    user = g.user
    if not user:
        # 用户未登录，重定向到主页
        return redirect('/')
    if request.method == "GET":
        data = {
            "user_info": user.to_dict() if user else None
        }
        return render_template("news/user_pic_info.html", data = data)

    # 1、获取上传的文件
    try:
        avatar_file = request.files.get('avatar').read()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno = RET.PARAMERR, errmsg = "读取文件出错")

    # 2. 再将文件上传到七牛云
    try:
        url = storage(avatar_file)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno = RET.THIRDERR, errmsg = "上传图片错误")

    # 3. 把头像信息更新到当前用户的模型中 user.avatar_url = storage返回的url ，并提交数据库
    # 设置用户模型相关数据
    user.avatar_url = url
    # 将数据保存到数据库
    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno = RET.DBERR, errmsg = "保存用户数据错误")

    # 4. 返回上传的结果(带上图片url返回给前端)
    return jsonify(errno=RET.OK, errmsg="OK", data={"avatar_url": constants.QINIU_DOMIN_PREFIX + url})  # 上传图片到七牛云


@profile_blu.route("/pass_info", methods=["GET", "POST"])
@user_login_data
def pass_info():
    # 实现修改密码功能
    user = g.user
    if not user:
        # 用户未登录，重定向到主页
        return redirect('/')

    if request.method == "GET":
        data = {
            "user_info": user.to_dict() if user else None
        }
        return render_template("news/user_pass_info.html", data=data)

    # 1、获取参数（旧密码新密码）、判空 、校验密码是否一致
    data_dict = request.json
    old_password = data_dict.get("old_password")
    new_password = data_dict.get("new_password")
    new_password2 = data_dict.get("new_password2")
    # 2、校验旧密码是否正确
    if not all([old_password, new_password, new_password2]):
        return jsonify(errno = RET.PARAMERR, errmsg = "参数错误")
    if new_password != new_password2:
        return jsonify(errno = RET.PARAMERR, errmsg = "两次密码不一致")
    if not user.check_passowrd(old_password):
        return jsonify(errno = RET.PARAMERR, errmsg = "旧密码错误")
    # 3、更新密码user.password = new_password  并提交数据
    user.password = new_password2
    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno = RET.DBERR, errmsg = "数据库操作失败")
    # 4、返回操作结果
    return jsonify(errno = RET.OK, errmsg = "保存成功")


@profile_blu.route("/collection")
@user_login_data
def collection():
    # 获取用户登陆信息
    user = g.user
    if not user:
        return redirect("/")

# 后端实现步骤：
# 1、获取参数(页码)  request.args.get("p", 1),配合前端传过来的当前页数，获取之后转整型
# 2、分页查询我的收藏
# 3、把查询到的数据转成字典
# 4、把数据返回给user_collection.html模板

    # 1、接收参数 (接收一个请求页码，默认是第一页)
    p = request.args.get('p', 1)
    try:
        p = int(p)
    except Exception as e:
        current_app.logger.error(e)
        p = 1
    # 2、分页查询数据库 user.collection_news.paginate(...)
    cur_page_news = []
    total_page = 1
    cur_page = 1
    try:
        paginate = user.collection_news.paginate(p, constants.USER_COLLECTION_MAX_NEWS, False)
        cur_page_news = paginate.items
        total_page = paginate.pages
        cur_page = paginate.page
    except Exception as e:
        current_app.logger.error(e)

    # 3、转换成字典
    cur_page_news_list = []
    for i in cur_page_news:
        cur_page_news_list.append(i.to_dict())

    # 4、返回结果
    data = {
        "cur_page_news_list": cur_page_news_list,  # 要返回用户收藏的新闻列表
        "total_page": total_page,   # 要返回总页数
        "cur_page": cur_page     # 要返回当前页数
    }
    return render_template("news/user_collection.html", data = data)


@profile_blu.route("/news_list")
@user_login_data
def news_list():
    # 获取用户登陆信息
    user = g.user
    if not user:
        return redirect("/")

    # 1、接收参数 (接收一个请求页码，默认是第一页)
    p = request.args.get('p', 1)
    try:
        p = int(p)
    except Exception as e:
        current_app.logger.error(e)
        p = 1
    # 2、分页查询数据库 user.collection_news.paginate(...)
    cur_page_news = []
    total_page = 1
    cur_page = 1
    try:
        paginate = user.news_list.order_by(News.create_time.desc()).paginate(p, constants.USER_COLLECTION_MAX_NEWS)
        cur_page_news = paginate.items
        total_page = paginate.pages
        cur_page = paginate.page
    except Exception as e:
        current_app.logger.error(e)

    # 3、转换成字典
    cur_page_news_list = []
    for i in cur_page_news:
        cur_page_news_list.append(i.to_review_dict())  # 带审核状态的字典

    # 4、返回结果
    data = {
        "cur_page_news_list": cur_page_news_list,  # 要返回用户收藏的新闻列表
        "total_page": total_page,   # 要返回总页数
        "cur_page": cur_page     # 要返回当前页数
    }
    return render_template("news/user_collection.html", data = data)


@profile_blu.route("/news_release", methods=["GET", "POST"])
@user_login_data
def news_release():
    # 获取用户登陆信息
    user = g.user
    if not user:
        return redirect("/")

    if request.method == "GET":
        # 查询新闻分类返回给前端展示
        try:
            categories = Category.query.all()
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno = RET.DBERR, errmsg = "数据库查询错误")

        data = {
            "user_info": user.to_dict() if user else None,
            "categories": categories
        }
        return render_template("news/user_news_release.html", data = data)

        # 1、获取参数、判空
        data_dict = request.form  # 接受表单通过post提交的数据
        title = data_dict.get("title")  # 新闻标题
        digest = data_dict.get("digest")  # 新闻摘要
        content = data_dict.get("content")  # 新闻内容
        index_image = request.files.get("index_image")  # 图片
        category_id = data_dict.get("category_id")  # 新闻分类id
        source = "个人发布"  # 新闻来源

        if not all([title, source, digest, content, index_image, category_id]):
            return jsonify(errno = RET.PARAMERR, errmsg = "参数有误")
        # 2. 把文件上传到七牛云
        try:
            # 读取图片的内容
            index_image = index_image.read()
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno = RET.PARAMERR, errmsg = "参数有误")

        try:
            index_image_filename = storage(index_image)
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno = RET.THIRDERR, errmsg = "上传图片错误")
        # 3、创建新闻模型、添加模型属性(记得设置状态)
        news = News()
        news.title = title
        news.digest = digest
        news.source = source
        news.content = content
        news.index_image_url = constants.QINIU_DOMIN_PREFIX + index_image_filename
        news.category_id = category_id

        news.user_id = user.id
        # 1代表待审核状态 (用户发布的信息，不能直接信任，需要审核)
        news.status = 1

        # 4、提交数据
        try:
            db.session.add(news)
            db.session.commit()
        except Exception as e:
            current_app.logger.error(e)
            db.session.rollback()
            return jsonify(errno = RET.DBERR, errmsg = "保存数据失败")

        # 5、返回结果
        return jsonify(errno = RET.OK, errmsg = "发布成功, 待审核")